<?php
/*
 * Image Helper
 *   help to create thumb image and mark image
 * 
 * //TODO add function toFile or toStream.
 * 
 * <code>
 * example: create thumb
 * $path = $image->file(array(APP_ROOT.'1.jpg', APP_ROOT . '2.jpg'))->to(IMAGE_ORG_DIR)->thumb()->getPath();
 * 
 * example: create text mark
 * $array = array('font:/var/www/mid/element/msyh.ttf;size:20;color:#000000'=>'key里面是文字的属性');
 * $path = $image->file(array(APP_ROOT.'1.jpg', APP_ROOT . '2.jpg'))->to(IMAGE_ORG_DIR)->mark($array)->getPath();
 * 
 * example: create water mark
 * $array = array(1=>'/var/www/mid/element/mark.png');
 * //position set[0:center; 1:left up; 2:right up; 3:right down; 4:left down]\
 * //TODO need change to commen function using type to select text or water mark
 * $path = $image->file(array(APP_ROOT.'1.jpg', APP_ROOT . '2.jpg'))->to(IMAGE_ORG_DIR)->mark($array)->getPath();
 * </code>
 */
define ( 'IMAGE_ORG_DIR', 'USE_ORG_DIR' );
define ( 'IMAGE_SUB_DIR', 'USE_SUB_DIR' );
define ( 'IMAGE_DIR_THUMB', 'thumb' );
define ( 'IMAGE_DIR_MARK', 'mark' );

class Helper_Image {
	protected $upPath;
	protected $thumbSub = '_thumb';
	protected $markSub = '_mark';
	protected $waterImg;
	protected $pool_to;
	protected $pool_file;
	protected $pool_path = false;
	protected $pool_error = false;
	
	public function file($file) {
		$this->pool_file = $file;
		return $this;
	}
	
	public function to($to) {
		$this->fixSep ( $to );
		$this->pool_to = $to;
		return $this;
	}
	
	public function thumb($data = '160,160') {
		$this->pool_path = false;
		$this->pool_error = false;
		if (! $this->pool_file || ! $this->pool_to) {
			return $this;
		}
		if (strpos ( $data, ',' ) === false) {
			return $this;
		}
		list ( $width, $height ) = explode ( ',', $data );
		$this->pool_path = $this->makeThumb ( $this->pool_file, $this->pool_to, $width, $height );
		return $this;
	}
	
	public function mark($data) {
		$this->pool_path = false;
		$this->pool_error = false;
		if (! $this->pool_file || ! $this->pool_to) {
			return $this;
		}
		$this->pool_path = $this->makeMark ( $this->pool_file, $this->pool_to, $data );
		return $this;
	}
	
	public function getPath() {
		return $this->pool_path;
	}
	
	public function getError() {
		return $this->pool_error;
	}
	
	protected function makeThumb($photo, $_thumbPath, $width = 180, $height = 180) {
		$path = false;
		if (is_array ( $photo )) {
			foreach ( $photo as $k => $p ) {
				$path [$k] = $this->makeThumb ( $p, $_thumbPath, $width, $height );
			}
		} else {
			if ($_thumbPath === IMAGE_ORG_DIR) {
				$_thumbPath = substr ( $photo, 0, strrpos ( $photo, DIR_SEP ) + 1 );
			} elseif ($_thumbPath === IMAGE_SUB_DIR || ! $_thumbPath) {
				$_thumbPath = substr ( $photo, 0, strrpos ( $photo, DIR_SEP ) + 1 ) . IMAGE_DIR_THUMB . DIR_SEP;
			}
			$imgInfo = $this->getInfo ( $photo );
			
			if ($imgInfo ["type"] == 1) {
				$img = imagecreatefromgif ( $photo );
				$ext = "gif";
			} elseif ($imgInfo ["type"] == 2) {
				$img = imagecreatefromjpeg ( $photo );
				$ext = "jpg";
			} elseif ($imgInfo ["type"] == 3) {
				$img = imagecreatefrompng ( $photo );
				$ext = "png";
			} else {
				$img = "";
			}
			if (empty ( $img ))
				return False;
			$newName = "thumb_" . substr ( $imgInfo ["name"], 0, strrpos ( $imgInfo ["name"], "." ) ) . "." . $ext;
			
			$width = ($width > $imgInfo ["width"]) ? $imgInfo ["width"] : $width;
			$height = ($height > $imgInfo ["height"]) ? $imgInfo ["height"] : $height;
			$srcW = $imgInfo ["width"];
			$srcH = $imgInfo ["height"];
			if ($srcW * $width > $srcH * $height) {
				$height = round ( $srcH * $width / $srcW );
			} else {
				$width = round ( $srcW * $height / $srcH );
			}
			if (function_exists ( "imagecreatetruecolor" )) {
				$newImg = imagecreatetruecolor ( $width, $height );
				$bgc = imagecolorallocate ( $newImg, 200, 210, 210 );
				imagefilledrectangle ( $newImg, 0, 0, $width, $height, $bgc );
				ImageCopyResampled ( $newImg, $img, 0, 0, 0, 0, $width, $height, $imgInfo ["width"], $imgInfo ["height"] );
			} else {
				$newImg = imagecreate ( $width, $height );
				$bgc = imagecolorallocate ( $newImg, 200, 210, 210 );
				imagefilledrectangle ( $newImg, 0, 0, $width, $height, $bgc );
				ImageCopyResized ( $newImg, $img, 0, 0, 0, 0, $width, $height, $imgInfo ["width"], $imgInfo ["height"] );
			}
			//if ($this->toFile) {
			if (substr ( $_thumbPath, - 1 ) != DIR_SEP)
				$_thumbPath .= DIR_SEP;
			if (! is_dir ( $_thumbPath ) && ! @mkdir ( $_thumbPath, 0777, true ))
				exit ( 'Helper Image Error: thumb path cann\'t be created' );
			$_thumbFilePath = $_thumbPath . $newName;
			
			if (file_exists ( $_thumbFilePath ))
				@unlink ( $_thumbFilePath );
			
			if ($imgInfo ["type"] == 1) {
				imagegif ( $newImg, $_thumbFilePath );
			} elseif ($imgInfo ["type"] == 2) {
				imagejpeg ( $newImg, $_thumbFilePath );
			} elseif ($imgInfo ["type"] == 3) {
				imagepng ( $newImg, $_thumbFilePath );
			}
			//ImageJPEG($newImg, $_thumbFilePath);
			//return $_thumbFilePath;
			/*} else {
				if ($imgInfo ["type"] == 1) {
					imagegif ( $newImg );
				} elseif ($imgInfo ["type"] == 2) {
					imagejpeg ( $newImg );
				} elseif ($imgInfo ["type"] == 3) {
					imagepng ( $newImg );
				}
				//ImageJPEG($newImg);
			}*/
			ImageDestroy ( $newImg );
			ImageDestroy ( $img );
			$path = $_thumbFilePath;
		}
		return $path;
	}
	
	protected function makeMark($photo, $_markPath, $text) {
		$path = false;
		if (is_array ( $photo )) {
			foreach ( $photo as $k => $p ) {
				$path [$k] = $this->makeMark ( $p, $_markPath, $text );
			}
		} else {
			if ($_markPath === IMAGE_ORG_DIR) {
				$_markPath = substr ( $photo, 0, strrpos ( $photo, DIR_SEP ) + 1 );
			} elseif ($_markPath === IMAGE_SUB_DIR || ! $_markPath) {
				$_markPath = substr ( $photo, 0, strrpos ( $photo, DIR_SEP ) + 1 ) . IMAGE_DIR_MARK . DIR_SEP;
			}
			if (! $imgInfo = $this->getInfo ( $photo ))
				return false;
			
			switch ($imgInfo ["type"]) {
				case 1 :
					$img = imagecreatefromgif ( $photo );
					$ext = "gif";
					break;
				case 2 :
					$img = imagecreatefromjpeg ( $photo );
					$ext = "jpg";
					break;
				case 3 :
					$img = imagecreatefrompng ( $photo );
					$ext = "png";
					break;
				default :
					return False;
			}
			if (empty ( $img ))
				return False;
			$newName = substr ( $imgInfo ["name"], 0, strrpos ( $imgInfo ["name"], "." ) ) . "_mark." . $ext;
			//$width = ($this->maxWidth > $imgInfo["width"]) ? $imgInfo["width"] : $this->maxWidth; 
			//$height = ($this->maxHeight > $imgInfo["height"]) ? $imgInfo["height"] : $this->maxHeight; 
			$width = $imgInfo ["width"];
			$height = $imgInfo ["height"];
			$srcW = $imgInfo ["width"];
			$srcH = $imgInfo ["height"];
			if ($srcW * $width > $srcH * $height) {
				$height = round ( $srcH * $width / $srcW );
			} else {
				$width = round ( $srcW * $height / $srcH );
			}
			if (function_exists ( "imagecreatetruecolor" )) {
				$newImg = imagecreatetruecolor ( $width, $height );
				$bgc = imagecolorallocate ( $newImg, 200, 210, 210 );
				imagefilledrectangle ( $newImg, 0, 0, $width, $height, $bgc ); //设置背景色
				ImageCopyResampled ( $newImg, $img, 0, 0, 0, 0, $width, $height, $imgInfo ["width"], $imgInfo ["height"] );
			} else {
				$newImg = imagecreate ( $width, $height );
				$bgc = imagecolorallocate ( $newImg, 200, 210, 210 );
				imagefilledrectangle ( $newImg, 0, 0, $width, $height, $bgc ); //设置背景色
				ImageCopyResized ( $newImg, $img, 0, 0, 0, 0, $width, $height, $imgInfo ["width"], $imgInfo ["height"] );
			}
			
			foreach ( $text as $var => $needle ) {
				if (! is_int ( $var )) {
					$alpha = 30;
					$size = 9;
					$pos_x = 10;
					$pos_y = 10;
					$angle = 0;
					$brush = imageColorAllocateAlpha ( $newImg, 0, 0, 0, $alpha );
					$data = $this->str2attr ( $var );
					foreach ( $data as $k => $v ) {
						switch ($k) {
							case 'color' :
								$color = $this->str2rgb ( $v );
								break;
							case 'size' :
								$size = $v;
								break;
							case 'pos' :
								list ( $pos_x, $pos_y ) = explode ( ',', $v );
								break;
							case 'font' :
								$font = $v;
								break;
							case 'angle' :
								$angle = $v;
								break;
							case 'alpha' :
								$alpha = $v;
								break;
						}
					}
					if (! $font) {
						return false;
					} else {
						if (! file_exists ( $font ))
							return false;
					}
					$brush = imageColorAllocateAlpha ( $newImg, $color ['r'], $color ['g'], $color ['b'], $alpha );
					ImageTTFText ( $newImg, $size, $angle, $pos_x, $pos_y + $size, $brush, $font, $needle );
					/*$white = imageColorAllocate ( $newImg, 255, 255, 255 );
					ImageFilledRectangle ( $newImg, 0, $height - 26, $width, $height, $alpha );
					ImageFilledRectangle ( $newImg, 13, $height - 20, 15, $height - 7, $black );*/
				} else {
					if (! $wInfo = $this->getInfo ( $needle ))
						return false;
					switch ($var) {
						case 0 :
							$des_x = ($imgInfo ["width"] - $wInfo ["width"]) / 2;
							$des_y = ($imgInfo ["height"] - $wInfo ["height"]) / 2;
							break;
						case 1 :
							$des_x = 0;
							$des_y = 0;
							break;
						case 2 :
							$des_x = $imgInfo ["width"] - $wInfo ["width"];
							$des_y = 0;
							break;
						case 3 :
							$des_x = $imgInfo ["width"] - $wInfo ["width"];
							$des_y = $imgInfo ["height"] - $wInfo ["height"];
							break;
						case 4 :
							$des_x = 0;
							$des_y = $imgInfo ["height"] - $wInfo ["height"];
							break;
						default :
							$des_x = 0;
							$des_y = 0;
					}
					switch ($wInfo ["type"]) {
						case 1 :
							$wImg = imagecreatefromgif ( $needle );
							break;
						case 2 :
							$wImg = imagecreatefromjpeg ( $needle );
							break;
						case 3 :
							$wImg = imagecreatefrompng ( $needle );
							break;
						default :
							return False;
					}
					imagecopy ( $newImg, $wImg, $des_x, $des_y, 0, 0, $wInfo ["width"], $wInfo ["height"] );
					imagedestroy ( $wImg );
				}
			}
			
			if (substr ( $_markPath, - 1 ) != DIR_SEP)
				$_markPath .= DIR_SEP;
			if (! is_dir ( $_markPath ) && ! @mkdir ( $_markPath, 0777, true ))
				return false;
			$_markFilePath = $_markPath . $newName;
			if (file_exists ( $_markFilePath ))
				@unlink ( $_markFilePath );
			if ($imgInfo ["type"] == 1) {
				imagegif ( $newImg, $_markFilePath );
			} elseif ($imgInfo ["type"] == 2) {
				imagejpeg ( $newImg, $_markFilePath );
			} elseif ($imgInfo ["type"] == 3) {
				imagepng ( $newImg, $_markFilePath );
			}
			/*} else {
				//ImageJPEG($newImg);
				if ($imgInfo ["type"] == 1) {
					$img = imagegif ( $newImg );
				} elseif ($imgInfo ["type"] == 2) {
					$img = imagejpeg ( $newImg );
				} elseif ($imgInfo ["type"] == 3) {
					$img = imagepng ( $newImg );
				}
			}*/
			ImageDestroy ( $newImg );
			ImageDestroy ( $img );
			$path = $_markFilePath;
		}
		return $path;
	}
	
	protected function setError($data) {
		$this->pool_error [] = $data;
	}
	
	protected function getInfo($photo) {
		if (! file_exists ( $photo )) {
			return false;
		}
		$imageInfo = getimagesize ( $photo );
		$imgInfo ["width"] = $imageInfo [0];
		$imgInfo ["height"] = $imageInfo [1];
		$imgInfo ["type"] = $imageInfo [2];
		$imgInfo ["name"] = basename ( $photo );
		return $imgInfo;
	}
	
	protected function str2rgb($str) {
		$color = substr ( $str, 1 );
		$arr ['r'] = hexdec ( substr ( $color, 0, 2 ) );
		$arr ['g'] = hexdec ( substr ( $color, 2, 2 ) );
		$arr ['b'] = hexdec ( substr ( $color, 4, 2 ) );
		//$s ="R:". hexdec(substr($color, 0, 2)) . " G:".hexdec(substr($color, 2, 2))." B:". hexdec(substr($color, 4, 2));
		return $arr;
	}
	
	protected function str2attr($str) {
		$data = array ();
		if (strpos ( $str, ';' ) !== false) {
			$arr = explode ( ';', $str );
			foreach ( $arr as $value ) {
				$pos = strpos ( $value, ':' );
				$k = trim ( substr ( $value, 0, $pos ) );
				$v = trim ( substr ( $value, $pos + 1 ) );
				$data [$k] = $v;
			}
		} else {
			$pos = strpos ( $str, ':' );
			$k = trim ( substr ( $str, 0, $pos ) );
			$v = trim ( substr ( $str, $pos + 1 ) );
			$data [$k] = $v;
		}
		return $data;
	}
	
	public function version() {
		return '1.0';
	}
	
	protected function fixSep(&$str) {
		if ($str && strpos ( $str, '/' ) !== false) {
			$str = str_replace ( '/', DIR_SEP, $str );
		}
	}
}
?>